package com.yyaccp.hncc.smsg.service.impl;

import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.config.sms.SmsLoginService;
import com.ruoyi.framework.config.sms.ValidCodeConfig;
import com.yyaccp.hncc.smsg.service.ShortMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.concurrent.TimeUnit;

/**
 * @author 天天向上 （john.yi@qq.com）
 * @date 2020/9/11.
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SmsService {
    private final ShortMessageService shortMessageService;
    private final StringRedisTemplate stringRedisTemplate;
    private final ValidCodeConfig validCodeConfig;
    private final SmsLoginService smsLoginService;

    public String sendValidCodeMessage(String phoneNumber) {
        String key = validCodeConfig.getValidCodeKeyPrefix() + ":" + phoneNumber;
        // 一个号码1分钟只能请求一次
        Long expire = stringRedisTemplate.getExpire(key, TimeUnit.MINUTES);
        if(expire != null && validCodeConfig.getValidCodeExpire() - expire <= 1 ) {
            return "请在1分钟后再重新请求";
        }
        // 同一ip一分钟只能请求一次
        String ipKey = validCodeConfig.getValidCodeKeyPrefix() + ":IP:" + IpUtils.getIpAddr(ServletUtils.getRequest());
        if(log.isInfoEnabled()) {
            log.info("客户端{}请求验证码", ipKey);
        }
        expire = stringRedisTemplate.getExpire(ipKey, TimeUnit.SECONDS);
        if(expire != null && expire > 0) {
            return "请在1分钟后再重新请求(同一主机)";
        }
        //检查手机号码是否存在
        if (!smsLoginService.isExists(phoneNumber)) {
            return "号码不存在";
        }
        // 发送验证码
        String code = randomValidCode(validCodeConfig.getValidCodeLength());
        String result = shortMessageService.sendValidCodeMessage(phoneNumber, code);
        if(ShortMessageService.SUCCESS.equals(result)) {
            stringRedisTemplate.opsForValue().set(key, code, validCodeConfig.getValidCodeExpire(), TimeUnit.MINUTES);
            stringRedisTemplate.opsForValue().set(ipKey, "1", 60, TimeUnit.SECONDS);
        }
        return result;
    }

    public String login(String phoneNumber, String validCode) {
        return smsLoginService.login(phoneNumber, validCode);
    }

    public static String randomValidCode(int length) {
        Assert.isTrue(length <= 10, "验证码长度不能超过10");
        return  ("" + Math.random()).substring(2, length + 2);
    }
}
